<?php
include "Array2XML.php";

$ini_file = isset ( $argv [1] ) ? $argv [1] : "umlparser.ini";
//$ini_file = isset ( $argv [1] ) ? $argv [1] : "/home/x/workspace/PHPParser/umlparser.ini";

$out_file_name;
$dirname == array();
$len_dirname;

$include_pattern;
$exclude_link_pattern;
$exclude_pattern;
$link_pattern;
$files = array ();

$index = array ();
$index_by_id = array ();
$index_count_id = 0;

main();

function main() {
	global $ini_file;
	global $dirname;
	global $files;
	global $out_file_name;
	global $include_pattern;
	global $exclude_link_pattern;
	global $exclude_pattern;
	global $link_pattern;
	global $out_file_name;
	global $dirname;
	global $len_dirname;	
	global $out_uml_xml;
	global $uml_xsl;
	
	
	init_from_ini_file ( $ini_file );
	printInit();
	
	foreach ($dirname as $name) {
		$len_dirname = strlen ( $name );		
		$dir_arr = scan_dir ( $name );
		$files = array_merge ( $files, array ($dir_arr) );
	}
	
	$converter = new Array2XML ( $out_file_name );
	$xmlStr = $converter->convert ( $files );
	
//	proccesXSLT($xsltFile, $xmlFile, $outXmlFile);
//	proccesXSLT($uml_xsl, $out_file_name, $out_uml_xml);
	
	print "\n down.\n";
}

function init_from_ini_file($iniFile) {
	global $include_pattern;
	global $exclude_link_pattern;
	global $exclude_pattern;
	global $link_pattern;
	global $out_file_name;
	global $dirname;
	global $out_uml_xml;
	global $uml_xsl;
	
	$ini_array = parse_ini_file ( $iniFile, true );
	if ($ini_array == false) {
		throw new Exception ( "Error open ini file $iniFile" );
	}
	
	$out_file_name = $ini_array ["out_xml_file_name"];
	$out_uml_xml = $ini_array ["out_uml_xml"];
	$uml_xsl = $ini_array ["uml_xsl"];
	$dirname = $ini_array ["dirname"];

	
	$exclude_link_pattern = $ini_array ["exclude_link_pattern"] ["pattern"];
	$exclude_pattern = $ini_array ["exclude_pattern"] ["pattern"];
	$include_pattern = $ini_array ["include_pattern"] ["pattern"];
	
	foreach ( $ini_array ["link_pattern"] as $name_atr => $arr ) {
		foreach ( $arr as $k => $v ) {
			$link_pattern [$k] [$name_atr] = $v;
		}
	}
}

function printInit() {
	global $include_pattern;
	global $exclude_link_pattern;
	global $exclude_pattern;
	global $link_pattern;
	global $out_file_name;
	global $dirname;
	global $ini_file;
	
	print "=== initialization from ini file $ini_file ========================== \n";
	print "out_xml_file_name = $out_file_name\n";
	print "\n dirname = \n";
	print_r ( $dirname );
	print "\n exclude_link_pattern = ";
	print_r ( $exclude_link_pattern );
	print "\n exclude_pattern = ";
	print_r ( $exclude_pattern );
	print "\n include_pattern = ";
	print_r ( $include_pattern );
	print "\n link_pattern = ";
	print_r ( $link_pattern );
	print "=== end initialization from ini file ========================== \n";
}

function proccesXSLT($xsltFile, $xmlFile, $outXmlFile) {
	// Load the XML source
	$xml = new DOMDocument;
	$xml->load($xmlFile);

	$xsl = new DOMDocument;
	$xsl->load($xsltFile);

// 	Configure the transformer
	$proc = new XSLTProcessor;
	$proc->importStyleSheet($xsl); // attach the xsl rules

	$proc->transformToURI($xml, $outXmlFile);
}

function scan_dir($dirname, $dir_name = "/") {
	global $exclude_path;
	// Открываем текущую директорию 
	$dir = opendir ( $dirname );
	if($dir == false) {
		throw new Exception("Error open direcotry $dirname");
	}
	//	$xml_dirs = "";
	$xml_dirs = array ();
	while ( ($file = readdir ( $dir )) !== false ) {
		$fullName = "$dirname/$file";
		if ($file != "." && $file != "..") {
			if (filterFiles ( $fullName )) {
				
				//					if(is_file($fullName) & fnmatch("*.php",$file)) {
				if (is_file ( $fullName )) {
					
					if (filterOnlyFiles ( $fullName )) {
						print "parse : $fullName\n";
						$file_xml = parse_file ( $file, $dirname );
						if (! empty ( $file_xml )) {
							$xml_dirs = array_merge ( $xml_dirs, array ($file_xml ) );
						}
					}
				
				} else if (is_dir ( $fullName )) {
					
					$r = scan_dir ( $fullName, $dir_name );
					if (! empty ( $r )) {
						$xml_dirs = array_merge ( $xml_dirs, array ($r ) );
					
					}
				}
			}
		}
	}
	// Закрываем директорию 
	closedir ( $dir );
	//	$xml_dirs = "1";
	if (! empty ( $xml_dirs )) {
		$xml = array ("dir" => array (//				"name" => getRelativeName($dirname)
"name" => getRelativeName ( $dir_name ), "fullname" => getRelativeName ( $dirname ), $xml_dirs ) );
		putIndex ( $xml, "dir" );
	}
	
	return $xml;
}

function parse_file($filename, $path) {
	global $index_by_id;
	global $index_count_id;
	$fullName = "$path/$filename";
	//	print "parse file $full_name\n";
	$file = fopen ( $fullName, 'r' );
	$lineNum = 0;
	$link_arr = array ();
	
	while ( $str = fgets ( $file, 1024 ) ) {
		$lineNum ++;
		$idx = getIncludeFile ( $str );
		if (! empty ( $idx )) {
			$index_count_id ++;
			print "\t link : $lineNum  $index_by_id[$idx]\n";
			$link = array ("link" => array ("id" => $index_count_id, "fileId" => $idx, "line" => $lineNum, "str" => $str ) );
			$link_arr = array_merge ( $link_arr, array ($link ) );
		}
	
	}
	
//	if (! empty ( $link_arr )) {
		// Только файлы со связями

		$file_arr = array ("file" => array ("name" => $filename, "path" => getRelativeName ( $path ), "fullName" => getRelativeName ( $fullName ), "ext" => extractExt ( $filename ), "links" => $link_arr ) );
		$id = putIndex ( $file_arr, "file" );
//	}
	fclose ( $file );
	
	return $file_arr;

}

function getIncludeFile($str) {
	global $exclude_link_path;
	global $index;
	global $link_pattern;
	$match = array ();
	$path_idx = 1;
	$name_idx = 3;
	$result_idx = 0;
	
	foreach ( $link_pattern as $arr ) {
		if (preg_match ( $arr ["pattern"], $str, $match )) {
			
			$path = $match [$arr ["path_idx"]];
			$name = $match [$arr ["name_idx"]];
			//				$ext = $match[$arr["ext_idx"]];
			$fullName = "$path/$name";
			
			if (filterLink ( $fullName )) {
				if (isset ( $index [$fullName] )) {
					$result_idx = $index [$fullName] ["id"];
				} else {
					$result_idx = putFileToStruct ( $path, $name, $fullName );
				}
			}
			break;
		}
	}
	return $result_idx;
}

/**
 * Возращает id
 */
function putFileToStruct($path, $name, $fullName) {
	global $files;
	$file = array ("file" => array ("name" => $name, "path" => $path, "fullName" => $fullName, "ext" => extractExt ( $name ) ) );
	$idx = putIndex ( $file, "file" );
	$files = array_merge ( $files, array ($file ) );
	
	return $idx;
}

function extractExt($fileName) {
	$ext = preg_match ( "<[.A-Za-z0-9_-]+[.]([A-Za-z0-9_-]+)>", $fileName, $match ) ? $match [1] : "";
	
	return $ext;
}

function putIndex(&$arr, $type) {
	global $index;
	global $index_count_id;
	global $index_by_id;
	
	$fullName = $arr [$type] ["fullName"];
	$index_count_id ++;
	$arr [$type] ["id"] = $index_count_id;
	$index [$fullName] = array ("id" => $index_count_id );
	$index_by_id [$index_count_id] = $fullName;
	
	//		print_r ($index[$fullName]);
	return $index_count_id;
}

function filterOnlyFiles($fileName) {
	global $include_pattern;
	return ! filter ( $fileName, $include_pattern, "include" );
}
function filterFiles($fileName) {
	global $exclude_pattern;
	return filter ( $fileName, $exclude_pattern, "exclude" );
}

function filterLink($fileName) {
	global $exclude_link_pattern;
	return filter ( $fileName, $exclude_link_pattern, "exclude link" );
}

function filter($str, $filter_arr, $print_str = "exclude") {
	
	$result = true;
	foreach ( $filter_arr as $pattern ) {
		if (preg_match ( $pattern, $str )) {
			$result = false;
			break;
		}
	}
	
	if (! $result) {
		print "$print_str : $str\n";
	}
	return $result;
}

function getRelativeName($file_name) {
	global $len_dirname;
	$str = ($len_dirname < strlen ( $file_name )) ? substr ( $file_name, $len_dirname ) : "/";
	return $str;
}

?>
